資料庫正規化是一個將資料庫設計成更高效、避免資料冗餘和資料異常(如插入、更新、刪除異常)的方法。正規化的過程通常通過將資料分解成更小、更相關的表格來完成,每個表格都只儲存單一主題的資料。
正規化過程通常遵循以下幾個標準形式(Normal Forms),每條規則都稱為「正規形式 Normal Form」。如果遵守第一條規則,資料庫就稱為屬於「第一正規形式」。如果遵守第二條以及第一條規則,資料庫就稱為屬於「第二正規形式」。如果遵守三條規則,資料庫就被視為屬於「第三正規形式」。
重複的資料會浪費磁碟空間,並產生維護方面的問題,不一致的相依性會讓資料出錯誤。
目的是去除重覆性的問題
一個違反 1NF 的表格可能長這樣:
OrderID | CustomerName | Items |
---|---|---|
1 | Alice | Pen, Pencil |
2 | Bob | Notebook, Pen |
這裡的 Items
欄位包含了多個值,這違反了 1NF 的規則。
將 Items
欄位拆分到一個獨立的表格中:
Orders
表:
OrderID | CustomerName |
---|---|
1 | Alice |
2 | Bob |
OrderItems
表:
OrderID | Item |
---|---|
1 | Pen |
1 | Pencil |
2 | Notebook |
2 | Pen |
去除部分功能相依的問題
假設有一個複合key的表格:
OrderID | ProductID | ProductName | Quantity |
---|---|---|---|
1 | 101 | Pen | 2 |
1 | 102 | Pencil | 3 |
2 | 101 | Pen | 5 |
ProductName
只依賴於 ProductID
而不是整個主鍵 (OrderID
, ProductID
),這違反了 2NF。
將 ProductName
分離到另一個表格:
OrderDetails
表:
OrderID | ProductID |
---|---|
1 | 101 |
1 | 102 |
Products
表:
ProductID | ProductName |
---|---|
101 | Pen |
102 | Pencil |
OrderID | CustomerName | CustomerAddress |
---|---|---|
1 | Alice | 123 Main St |
2 | Bob | 456 Oak St |
3 | Alic | 123 Main St |
CustomerAddress
依賴於不是主鍵的 CustomerName
,而不是直接依賴於主鍵 OrderID
,這違反了 3NF原則,因為非主鍵欄位之間不應該存在依賴關係。
將 CustomerName
和 CustomerAddress
分離成一個獨立的 Customers
表,然後在 Orders
表中僅儲存 CustomerID
:
Customers
表:
CustomerID | CustomerName | CustomerAddress |
---|---|---|
1 | Alice | 123 Main St |
2 | Bob | 456 Oak St |
Orders
表:
OrderID | CustomerID |
---|---|
1 | 1 |
2 | 2 |
3 | 1 |
還有一些更高級的正規形式如 Boyce-Codd 正規形式 (BCNF)、第四正規形式 (4NF) 和第五正規形式 (5NF),但大多數情況下,達到 3NF 就已經能夠滿足大部分的設計需求,並大大減少資料異常的可能性。
資料庫正規化的目的是確保資料的一致性和完整性,減少冗餘,同時提高資料庫的效率。好好地遵守,可以幫助我們的執行速度上加快不少!
https://learn.microsoft.com/en-us/office/troubleshoot/access/database-normalization-description
https://www.mysql.tw/2013/03/normalization.html